from elasticsearch import Elasticsearch, exceptions
import logging
from ding import tools
from datetime import datetime


def es_connect():
    """
    创建ES连接
    :return:
    """
    es_cf = dict(tools.cf_connect().items('es'))
    port = es_cf['port']
    host = es_cf['host']

    if 'username' in es_cf.keys() and 'password' in es_cf.keys():
        try:
            username = es_cf['username']
            pw = es_cf['password']
            de_password = tools.salsa_decrypt(pw).decode()
            de_username = tools.salsa_decrypt(username).decode()
            es = Elasticsearch(hosts=f"http://{host}", port=port, http_auth=f"{de_username}:{de_password}")
            return es
        except UnicodeDecodeError as ex:
            logging.error(f"ES账号或密码未加密！{ex}")

    else:
        es = Elasticsearch(hosts=f"http://{host}", port=port)
        return es


def db_status():
    """
    数据库启用判断
    :return: True/False
    """
    status = tools.cf_connect('settings', 'db')
    if status in 'enable':
        return True
    else:
        return False


def es_init():
    """
    ES初始化
    :return:
    """
    es = es_connect()
    index_name = tools.cf_connect('es', 'index_name')
    body = {
        "mappings": {
            "properties": {
                "@timestamp": {
                    "type": "date"
                },
                "TS": {
                    "type": "date"
                }
            }
        },
        "settings": {
            "index": {
                "number_of_shards": "1",
                "analysis": {
                    "analyzer": {
                        "splitAnalyzer": {
                            "lowercase": "false",
                            "pattern": "\\,|\\s|\\||、|，|:|：",
                            "type": "pattern"
                        },
                        "charAnalyzer": {
                            "type": "standard",
                            "max_token_length": "1"
                        }
                    }
                },
                "number_of_replicas": "1"
            }
        }
    }
    try:
        es.search(index=index_name)
    except exceptions.NotFoundError as e:
        logging.error(f"{e} 索引不存在，开始初始化...")
        es.indices.create(index=index_name, body=body)
        logging.info("初始化完成！")
    except exceptions.ConnectionError as ex:
        logging.error(f"ES连接失败！{ex}")


def msg_save(alert_msg: dict):
    """
    告警信息保存
    :param alert_msg: 需要推送的告警信息
    """
    if db_status():
        # 取时间差
        alert_msg['duration'] = time_difference(alert_msg)
        es = es_connect()
        index_name = tools.cf_connect('es', 'index_name')
        try:
            es.index(index=index_name,document=alert_msg)
        except exceptions.RequestError as ex:
            logging.error(f'告警信息无法存储，请检查索引! {ex}')


def time_difference(alert_msg: dict):
    """
    取时间差,返回告警持续时间
    :param alert_msg: 告警信息
    """
    end_time = datetime.strptime(str(alert_msg['end_time']), "%Y-%m-%d %H:%M:%S")
    start_time = datetime.strptime(str(alert_msg['start_time']), "%Y-%m-%d %H:%M:%S")
    diff = end_time - start_time
    day = diff.days
    hour, remainder = divmod(diff.seconds, 3600)
    minute, second = divmod(remainder, 60)

    duration = '{}d, '.format(day) if day else ''
    duration += '{}h, '.format(hour) if hour else ''
    duration += '{}m'.format(minute) if minute else ''

    if day or hour or minute:
        duration += '{}s'.format(second)
    else:
        duration = '{}s'.format(second)
    return duration
